<?php

namespace Nece\Sdk\Coze\Api;

use Nece\Sdk\Coze\ApiAbstract;

/**
 * 工作流
 *
 * @author gjw
 * @created 2025-04-23 15:42:02
 */
class Workflow extends ApiAbstract
{
    /**
     * 执行工作流
     * 文档：https://www.coze.cn/open/docs/developer_guides/workflow_run
     * 
     * @author gjw
     * @created 2025-04-23 15:32:54
     *
     * @param string $workflow_id 待执行的 Workflow ID，此工作流应已发布。
     * @param array $parameters 工作流开始节点的输入参数及取值，以 JSON 序列化字符串形式传入。
     * @param string $bot_id 需要关联的智能体 ID。
     * @param string $app_id 该工作流关联的应用的 ID
     * @param array $ext 用于指定一些额外的字段，以 Map[String][String] 格式传入。
     * @param boolean $is_async 是否异步运行。异步运行后可通过本接口返回的 execute_id 调用查询工作流异步执行结果API 获取工作流的最终执行结果。true：异步运行。false：（默认）同步运行。
     * @return array
     */
    public function run(string $workflow_id, array $parameters = [], string $bot_id = '', string $app_id = '', array $ext = [], bool $is_async = false)
    {
        $api = '/v1/workflow/run';

        $params = array(
            'workflow_id' => $workflow_id,
            'is_async' => $is_async,
        );

        if (!empty($parameters)) {
            $params['parameters'] = $parameters;
        }

        if (!empty($bot_id)) {
            $params['bot_id'] = $bot_id;
        }

        if (!empty($app_id)) {
            $params['app_id'] = $app_id;
        }
        if (!empty($ext)) {
            $params['ext'] = $ext;
        }

        return $this->post($api, $params);
    }

    /**
     * 恢复运行工作流
     * 文档：https://www.coze.cn/open/docs/developer_guides/workflow_resume
     *
     * @author gjw
     * @created 2025-04-23 15:35:59
     *
     * @param string $workflow_id 待执行的 Workflow ID，此工作流应已发布。
     * @param string $event_id 工作流执行中断事件 ID。你可以从执行工作流（流式响应）的响应信息中获得中断事件 ID。
     * @param string $resume_data 恢复执行时，用户对智能体指定问题的回复。
     * @param integer $interrupt_type 中断类型，你可以从执行工作流（流式响应）的响应信息中获得中断时间的中断类型。
     * @return array
     */
    public function resume(string $workflow_id, string $event_id, string $resume_data, int $interrupt_type)
    {
        $api = '/v1/workflow/stream_resume';
        $params = array(
            'workflow_id' => $workflow_id,
            'event_id' => $event_id,
            'resume_data' => $resume_data,
            'interrupt_type' => $interrupt_type,
        );

        return $this->post($api, $params);
    }

    /**
     * 查询工作流异步执行结果
     *
     * @author gjw
     * @created 2025-04-23 15:37:54
     *
     * @param string $workflow_id 待执行的 Workflow ID，此工作流应已发布。
     * @param string $execute_id 工作流执行 ID。调用接口执行工作流，如果选择异步执行工作流，响应信息中会返回 execute_id。
     * @return array
     */
    public function history(string $workflow_id, string $execute_id)
    {
        $api = '/v1/workflows/{{workflow_id}}/run_histories/{{execute_id}}';
        $api = str_replace(array('{{workflow_id}}', '{{execute_id}}'), array($workflow_id, $execute_id), $api);

        return $this->get($api);
    }

    /**
     * 执行对话流
     *
     * @author gjw
     * @created 2025-04-23 15:41:46
     *
     * @param string $workflow_id 待执行的对话流 ID，此对话流应已发布。
     * @param array $additional_messages 对话中用户问题和历史消息。数组长度限制为 50，即最多传入 50 条消息。
     * @param array $parameters 设置对话流输入参数中的自定义参数。你可以根据实际业务需求，通过parameters 参数传入自定义参数以及对应的值。
     * @param string $app_id 需要关联的扣子应用 ID。调用对话流时，必须指定 app_id 或 bot_id，便于模型调用智能体或应用的数据库、变量等数据处理问题。
     * @param string $bot_id 需要关联的智能体 ID。 调用对话流时，必须指定 app_id 或 bot_id，便于模型调用智能体或应用的数据库、变量等数据处理问题。
     * @param string $conversation_id 对话流对应的会话 ID，对话流产生的消息会保存到此对话中。会话默认为开始节点设置的 CONVERSATION_NAME，也可以通过 conversation_id 参数指定会话。
     * @param array $ext 用于指定一些额外的字段，以 Map[String][String] 格式传入。例如某些插件会隐式用到的经纬度等字段。
     * @param string $workflow_version 对话流的版本号，仅当运行的对话流属于资源库对话流时有效。未指定版本号时默认执行最新版本的对话流。
     * @return array
     */
    public function chat(string $workflow_id, array $additional_messages, array $parameters, string $app_id = '', string $bot_id = '', string $conversation_id = '', array $ext = [], string $workflow_version = '')
    {
        $api = '/v1/workflows/chat';
        $params = array(
            'workflow_id' => $workflow_id,
            'additional_messages' => $additional_messages,
            'parameters' => $parameters,
        );

        if ($app_id) {
            $params['app_id'] = $app_id;
        }
        if ($bot_id) {
            $params['bot_id'] = $bot_id;
        }
        if ($conversation_id) {
            $params['conversation_id'] = $conversation_id;
        }
        if ($ext) {
            $params['ext'] = $ext;
        }
        if ($workflow_version) {
            $params['workflow_version'] = $workflow_version;
        }

        return $this->post($api, $params);
    }

    /**
     * 查询输出节点的执行结果
     *
     * @author gjw
     * @created 2025-08-05 09:20:51
     *
     * @param string $workflow_id 要执行的 Workflow ID，需要先完成发布 Workflow 的操作。
     * @param string $execute_id 工作流的执行 ID。调用接口执行工作流，如果选择异步执行工作流，响应信息中会返回 execute_id。
     * @param string $node_execute_uuid 工作流异步执行结果 API 中返回的节点执行 uuid。
     * @return array
     */
    public function listRunHistory($workflow_id, $execute_id, $node_execute_uuid)
    {
        $api = '/v1/workflows/:workflow_id/run_histories/:execute_id/execute_nodes/:node_execute_uuid';
        $api = str_replace(array(':workflow_id', ':execute_id', ':node_execute_uuid'), array($workflow_id, $execute_id, $node_execute_uuid), $api);
        return $this->get($api);
    }

    /**
     * 查询工作流列表
     *
     * @author gjw
     * @created 2025-08-05 09:24:51
     *
     * @param string $workspace_id 工作空间 ID，用于指定要查询的工作空间。
     * @param integer $page_num 查询结果分页展示时，此参数用于设置查看的页码。最小值为 1。
     * @param integer $page_size 查询结果分页展示时，此参数用于设置每页返回的数据量。取值范围为 1 ~ 30，默认为 10。
     * @param string $workflow_mode 工作流类型，默认为空，即查询所有工作流类型。枚举值：workflow：工作流。chatflow：对话流。
     * @param string $app_id 扣子应用 ID，用于查询指定应用关联的工作流。默认为空，即不指定应用。
     * @param string $publish_status 工作流的发布状态，用于筛选不同发布状态的工作流。枚举值：all ：所有状态。published_online ：（默认值）已发布的正式版。unpublished_draft ：当前为草稿状态。
     * @return array
     */
    public function listWorkflow($workspace_id, $page_num = 1, $page_size = 10, $workflow_mode = 'workflow', $app_id = null, $publish_status = 'published_online')
    {
        $api = '/v1/workflows';
        $query = array(
            'workspace_id' => $workspace_id,
            'page_num' => $page_num,
            'page_size' => $page_size,
            'workflow_mode' => $workflow_mode,
            'publish_status' => $publish_status,
        );

        if ($app_id) {
            $query['app_id'] = $app_id;
        }

        return $this->get($api, $query);
    }

    /**
     * 查询工作流基本信息
     *
     * @author gjw
     * @created 2025-08-05 09:26:10
     *
     * @param string $workflow_id 工作流 ID。
     * @return array
     */
    public function getMetaData($workflow_id)
    {
        $api = '/v1/workflows/:workflow_id';
        $api = str_replace(':workflow_id', $workflow_id, $api);
        return $this->get($api);
    }

    /**
     * 查询工作流的版本列表
     *
     * @author gjw
     * @created 2025-08-05 09:27:29
     *
     * @param string $workflow_id 工作流 ID。
     * @return array
     */
    public function listVersion($workflow_id)
    {
        $api = '/v1/workflows/:workflow_id/versions';
        $api = str_replace(':workflow_id', $workflow_id, $api);
        return $this->get($api);
    }
}
